﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Dynamic;
using System.Transactions;
using PagedList;
using Sovigaz.DataProvider;
using Utilities;

namespace Sovigaz.Permission.Repositories
{
    public class CommandRepository : GenericRepository
    {
        public CommandRepository()
            : base("CommandID")
        {
        }

        public ICollection<CommandComplex> Commands { get; set; }

        public void Delete(Command command)
        {
            if (command != null)
            {
                if (command.Status == CommandStatus.N.ToString())
                {
                    _context.Commands.Remove(command);
                    var repository = new DeliveryPlanRepository();
                    repository.UpdateStatus(command.DeliveryPlanID, DeliveryPlanStatus.N.ToString());
                    _context.SaveChanges();
                }
            }
        }
        
        public void Delete(int id)
        {
            var item = GetByID(id);
            Delete(item);
        }

        public void Delete(string[] idArr)
        {
            foreach (var id in idArr)
                Delete(ConvertUtility.IntParse(id));
        }

        public int Update(Command command)
        {
            if (command.CommandLines.Count <= 0)
                return -1;
            var update = new Command();

            using (var scope = new TransactionScope())
            {
                if (command.CommandID > 0)
                {
                    update = GetByID(command.CommandID);
                    if (!Utility.ArrayEqual(update.Tstamp, command.Tstamp))
                        throw ExceptionHelper.CreateHttpResponseException("Dữ liệu đã bị cập nhật bởi người sử dụng khác.");
                }
                if (update.CommandID == 0)
                    _context.Commands.Add(update);
                _context.SaveChanges();


                scope.Complete();
            }

            _context.Entry(update).Reload();

            return update.CommandID;
        }

        public Command GetByID(int id)
        {
            var command = _context.Commands.FirstOrDefault(p => p.CommandID == id && !p.IsDeleted);
            if (command == null) return command;

            DeliveryPlan deliveryPlan=_context.DeliveryPlans.FirstOrDefault(p => p.DeliveryPlanID == command.DeliveryPlanID);

            //Get CommandLines
            var repository = new CommandLineRepository();
            command.CommandLines = repository.GetByCommandID(id);

            //Get DeliveryPlanCode
            command.DeliveryPlanCode = deliveryPlan.DeliveryPlanCode;

            //Get Taixe, Bocxep
            command.TaixeBocxep = string.Empty;
            if (deliveryPlan.UserID > 0)
            {
                command.TaixeBocxep = _context.Users.FirstOrDefault(u => u.UserID == deliveryPlan.UserID).FullName;
                if (deliveryPlan.BocXep1 > 0)
                    command.TaixeBocxep += "-" + _context.Users.FirstOrDefault(u => u.UserID == deliveryPlan.BocXep1).FullName;
                if (deliveryPlan.BocXep2 > 0)
                    command.TaixeBocxep += "-" + _context.Users.FirstOrDefault(u => u.UserID == deliveryPlan.BocXep2).FullName;
                if (deliveryPlan.BocXep3 > 0)
                    command.TaixeBocxep += "-" + _context.Users.FirstOrDefault(u => u.UserID == deliveryPlan.BocXep3).FullName;
            }


            return command;
        }

        public CommandRepository GetList(string whereClause, string orderBy, string orderDirection, int pageNumber)
        {
            var query = _context.Commands.Where(whereClause)
                .Join(_context.Users,c=>c.UserID,u=>u.UserID,
                (c,u)=>new {c,u})
                .Join(_context.Users,cu=>cu.c.CreatedBy,uu=>uu.UserID,(cu,uu)=> new CommandComplex()
                    {
                        CommandID = cu.c.CommandID,
                        CommandCode = cu.c.CommandCode,
                        UserName = cu.u.FullName,
                        LicensePlate = cu.c.LicensePlate,
                        PlanQty =  _context.CommandLines.Where(k => k.CommandID == cu.c.CommandID).Sum(k => k.PlanQty),
                        ShippedQty = _context.CommandLines.Where(k => k.CommandID == cu.c.CommandID).Sum(k => k.ShippedQty),
                        ReceivedQty = _context.CommandLines.Where(k => k.CommandID == cu.c.CommandID).Sum(k => k.ReceivedEmptyQty) + _context.CommandLines.Where(k => k.CommandID == cu.c.CommandID).Sum(k => k.ReceivedFullQty),
                        Date = cu.c.Date,
                        Status = cu.c.Status,
                        Description = cu.c.Description,
                        CreatedName=uu.FullName,
                        CreatedDate=cu.c.CreatedDate
                    })
                .OrderBy(String.Format("{0} {1}", orderBy.Trim(), orderDirection.Trim()))
                .ToPagedList(pageNumber, DefaultPageSize);

            TotalItemCount = query.TotalItemCount;
            TotalItemOnPage = query.Count;
            PageCount = query.PageCount;
            PageNumber = query.PageNumber;
            Commands = query.ToList();

            return this;
        }

        private bool CheckDeliveryPlanID(int id)
        {
            if (_context.Commands.Select(p => p.DeliveryPlanID == id && !p.IsDeleted).ToList().Count > 0) return true;
            return false;
        }

        public Command GetByDeliveryPlanID(int id)
        {
            return _context.Commands.FirstOrDefault(p => p.DeliveryPlanID == id && !p.IsDeleted);
        }
        
        public void CreateCommandFromDeliveryPlan(string[] idDeliveryPlanArr)
        {
            DeliveryPlanRepository deliveryPlanRepository = new DeliveryPlanRepository();
            CommandLineRepository commandLineRepository = new CommandLineRepository();
            DeliveryPlan deliveryPlan;
            Command command;
            using (var scope = new TransactionScope())
            {
                foreach (var id in idDeliveryPlanArr)
                {
                    deliveryPlan = deliveryPlanRepository.GetByID(ConvertUtility.IntParse(id));
                    if (deliveryPlan.DeliveryType == DeliveryPlanType.IN.ToString()) continue;
                    command = GetByDeliveryPlanID(deliveryPlan.DeliveryPlanID);
                    if (command != null) Delete(command.CommandID);
                    command = new Command();
                    command.DeliveryPlanID = deliveryPlan.DeliveryPlanID;                    
                    command.UserID = deliveryPlan.UserID;
                    command.Date = deliveryPlan.Date;
                    command.LicensePlate = _context.LicensePlates.FirstOrDefault(l => l.LicensePlateID == deliveryPlan.LicensePlate).LicensePlateName;
                    command.Description = deliveryPlan.Description;
                    command.Status = CommandStatus.N.ToString();
                        command.CommandCode = GenerateCode.GetCode(GetNextIndex(), CodeType.Command);
                        _context.Commands.Add(command);
                    _context.SaveChanges();
                    _context.Entry(command).Reload();
                    commandLineRepository.Update(deliveryPlan, command.CommandID, scope);                    
                }
                scope.Complete();
            }
        }

        public int GetNextIndex()
        {
            if (_context.Commands.FirstOrDefault() == null) return 1;
            return _context.Commands.Max(p => p.CommandID) + 1;
        }
    }
}
